/*** Created Time: 2022年5月13日 16:15:33 ***/
/*** Author: Eric                        ***/

#ifndef _MY_STDARG_H_
#define _MY_STDARG_H_

// 实现可变参数宏

// 参考标准库的stdarg.h头文件

// _INTSIZEOF宏作用是对n类型取int长度的倍数，结果向上取整
// 以sizeof(int) = 4(即32位机和64位机举例)
// 1、~(sizeof(int) - 1) = ~(0b0000_0011) = 0b1111_1100，任意一个数字x与上~(sizeof(int) - 1)
//     后最后两位肯定为0，因此肯定是4的整数倍
// 2、(sizeof(n) + sizeof(int) - 1)的作用是将大于4m但小于等于4(m+1)的数n提高到大于等于4(m+1)但
//     小于4(m+2)
#define _INTSIZEOF(n)       ((sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1))

// 定义一个char类型的指针
typedef char *va_list;

// va_start宏初始化ap(va_list)类型， 同时得到下一个参数的地址
#define va_start(ap, v)     (ap = (va_list)&v + _INTSIZEOF(v))

// va_arg宏有两个参数，一个是字符类型指针ap，另一个为类型t，即要在ap这个起始地址取出的数据的类型
// va_arg宏把char *类型的指针ap转换为t类型的指针ap，然后再解引用
// va_arg宏同时还使ap指向下一个参数的地址，即ap += _INTSIZEOF(t)
#define va_arg(ap, t)       (*(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)))

//  va_end宏结束可变参数的获取
#define va_end(ap)          (ap = (va_list)0)

#endif